package tt.dz.util;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSONObject;

public class HttpUtil {

	private static PoolingHttpClientConnectionManager connMgr;
	private static RequestConfig requestConfig;
	private static final int MAX_TIMEOUT = 1000 * 60;
	private static final String CHARSET = "UTF-8";
	/**ssl链接配置*/
	private static SSLConnectionSocketFactory sslConnectionSocketFactory;

	static {

		// 设置连接池
		connMgr = new PoolingHttpClientConnectionManager();
		
		// 设置连接池大小
		connMgr.setMaxTotal(100);
		connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());

		RequestConfig.Builder configBuilder = RequestConfig.custom();
		// 设置连接超时
		configBuilder.setConnectTimeout(MAX_TIMEOUT);
		// 设置读取超时
		configBuilder.setSocketTimeout(MAX_TIMEOUT);
		// 设置从连接池获取连接实例的超时
		configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
		// 在提交请求之前 测试连接是否可用
		// configBuilder.setStaleConnectionCheckEnabled(true);
		requestConfig = configBuilder.build();
	}

	/**
	 * 发送 post请求访问本地应用并根据传递参数不同返回不同结果
	 * 
	 * @param url
	 * @param paramMap
	 * @return
	 */
	public static String postRequest(String url, Map<String, String> paramMap) {

		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = HttpClients.custom()
				.setDefaultRequestConfig(requestConfig).build();
		
		// 创建httppost
		HttpPost httpPost = new HttpPost(url);
		// 创建参数队列
		List<NameValuePair> requestParams = new ArrayList<NameValuePair>();

		// 设置请求参数
		if (paramMap != null) {
			for (Iterator<String> iter = paramMap.keySet().iterator(); iter.hasNext();) {
				// 得到参数名
				String key = iter.next();
				requestParams.add(new BasicNameValuePair(iter.next(), paramMap.get(key)));
			}
		}
		UrlEncodedFormEntity formEntity;
		try {
			formEntity = new UrlEncodedFormEntity(requestParams, "UTF-8");
			httpPost.setEntity(formEntity);
			CloseableHttpResponse response = httpClient.execute(httpPost);
			try {
				HttpEntity entity = response.getEntity();
				return EntityUtils.toString(entity, "UTF-8");
			} finally {
				response.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * http post
	 */
	public static String postRequest(String url, Map<String, String> headerMap, Map<String, String> paramMap) {

		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = HttpClients.custom()
				.setDefaultRequestConfig(requestConfig).build();
		
		// 创建httppost
		HttpPost httpPost = new HttpPost(url);

		//设置请求头
		if(headerMap != null && headerMap.size() > 0){
			for(Map.Entry<String, String> entry : headerMap.entrySet()){
				httpPost.addHeader(entry.getKey(), entry.getValue());
			}
		}
		try {
			//设置请求参数
			if(paramMap != null && paramMap.size() > 0){
				List<NameValuePair> formparams = new ArrayList<NameValuePair>();
				for(Entry<String, String> entry : paramMap.entrySet()){
					formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
				UrlEncodedFormEntity requestEntity = new UrlEncodedFormEntity(formparams, CHARSET);
				httpPost.setEntity(requestEntity);
			}
			CloseableHttpResponse response = httpClient.execute(httpPost);
			try {
				HttpEntity entity = response.getEntity();
				return EntityUtils.toString(entity, CHARSET);
			} finally {
				response.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * http post
	 */
	public static String postRequest(String url, Map<String, String> headerMap, String jsonStr) {

		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = HttpClients.custom()
				.setDefaultRequestConfig(requestConfig).build();
		
		// 创建httppost
		HttpPost httpPost = new HttpPost(url);

		//设置请求头
		if(headerMap != null && headerMap.size() > 0){
			for(Map.Entry<String, String> entry : headerMap.entrySet()){
				httpPost.addHeader(entry.getKey(), entry.getValue());
			}
		}
		try {
			StringEntity strEntity = new StringEntity(jsonStr, ContentType.create("application/json", CHARSET));
			httpPost.setEntity(strEntity);
			CloseableHttpResponse response = httpClient.execute(httpPost);
			try {
				HttpEntity entity = response.getEntity();
				return EntityUtils.toString(entity, CHARSET);
			} finally {
				response.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 发送 get请求
	 * 
	 * @param urlValue
	 * @param paramMap
	 * @return
	 */
	public static String getRequest(String urlValue, Map<String, String> paramMap) {

		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = HttpClients.custom()
				.setDefaultRequestConfig(requestConfig).build();
		try {

			boolean firstAppend = true;

			if (paramMap != null && paramMap.size() > 0) {
				for (String key : paramMap.keySet()) {
					Object value = paramMap.get(key);
					if (firstAppend) {
						if (urlValue.contains("?")) {
								urlValue += "&" + key + "=" + value;
						} else {
								urlValue += "?" + key + "=" + value;
						}
						firstAppend = false;
					} else {
						urlValue += "&" + key + "=" + value;
					}
				}
			}
			// 创建httpget.
			HttpGet httpGet = new HttpGet(urlValue);
			System.out.println("executing request " + httpGet.getURI());
			// 执行get请求.
			CloseableHttpResponse response = httpClient.execute(httpGet);
			try {
				// 获取响应实体
				HttpEntity entity = response.getEntity();
				System.out.println("--------------------------------------");
				// 打印响应状态
				if (entity != null) {
					// 打印响应内容长度
					// 打印响应内容
					return EntityUtils.toString(entity);
				}
			} finally {
				response.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 重写方法，取消SSL验证
	 */
	private static X509TrustManager manager = new X509TrustManager() {
		
		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
		@Override
		public void checkServerTrusted(X509Certificate[] arg0, String arg1)
				throws CertificateException {
			
		}
		@Override
		public void checkClientTrusted(X509Certificate[] arg0, String arg1)
				throws CertificateException {
		}
	};
	
	/**
	 * 启用ssl
	 */
	private static void enableSSL(){
		try {
			SSLContext sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, new TrustManager[] {manager}, null);
			sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 发送SSL请求
	 * @param reqURL
	 * @param paramMap
	 * @param jsonSubmit
	 * @return
	 */
	public static String sendSSLPostRequest(String reqURL,
			Map<String, String> paramMap,boolean jsonSubmit) {

		enableSSL();
		
		RequestConfig reqConfig = RequestConfig.custom().setExpectContinueEnabled(true)
				.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM,AuthSchemes.DIGEST))
				.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
		
		Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
				.<ConnectionSocketFactory> create()
				.register("http", PlainConnectionSocketFactory.INSTANCE)
				.register("https", sslConnectionSocketFactory).build();

		// 设置连接池
		PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
		
		//获取httpclient
		CloseableHttpClient httpClient = HttpClients.custom()
				.setConnectionManager(clientConnectionManager)
				.setDefaultRequestConfig(reqConfig).build();
		HttpPost httpPost = new HttpPost(reqURL);
		
		try {
			if(!jsonSubmit){
				// 创建参数队列
				List<NameValuePair> requestParams = new ArrayList<NameValuePair>();
		
				// 设置请求参数
				if (paramMap != null) {
					for (Iterator<String> iter = paramMap.keySet().iterator(); iter.hasNext();) {
						// 得到参数名
						String key = iter.next();
						String value = paramMap.get(key);
						requestParams.add(new BasicNameValuePair(key, value));
					}
				}
				//表单编码实体
				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(requestParams, "UTF-8");
				httpPost.setEntity(formEntity);
				httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
			}
			else{
				StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(paramMap),"UTF-8");
				httpPost.setEntity(stringEntity);
				httpPost.setHeader("Content-Type", "application/json");
			}
			
			//执行请求
			CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpPost);
			HttpEntity entity =	closeableHttpResponse.getEntity();
			return EntityUtils.toString(entity);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}finally {
			// 关闭连接,释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {

		Map<String, String> map = new HashMap<String, String>();
		map.put("username", "你麻痹6");
		map.put("password", "137964635qq_com1");
//		String resultStr = HttpUtil.sendSSLPostRequest(
//				"http://a1.easemob.com/leeyx/dianzhuang/users", map, true);
		String resultStr1 = HttpUtil.getRequest("http://www.baidu.com", map);
		System.out.println(resultStr1);
	}
}
